package ufc.sd.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import me.prettyprint.cassandra.model.CqlQuery;
import me.prettyprint.cassandra.model.CqlRows;
import me.prettyprint.cassandra.service.template.ColumnFamilyResult;
import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;
import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
import me.prettyprint.hector.api.beans.Row;
import me.prettyprint.hector.api.exceptions.HectorException;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.QueryResult;
import ufc.sd.entities.Aluno;

public final class AlunoDAO extends CassandraDAO<Aluno> {

	protected static final String CF_ALUNO = "Aluno";
	private static final String COLUNA_NOME;
	private static final String COLUNA_IRA;
	private static final String COLUNA_CURSO;
	private static final String COLUNA_DT_NASCIMENTO;
	private static AlunoDAO instance;
	private static ColumnFamilyTemplate<String, String> alunoTemplate;

	static {
		COLUNA_NOME = "nome";
		COLUNA_IRA = "ira";
		COLUNA_CURSO = "curso";
		COLUNA_DT_NASCIMENTO = "dataNascimento";
	}

	public static AlunoDAO getInstance() {
		if (instance == null) {
			instance = new AlunoDAO();
		}
		return instance;
	}

	private AlunoDAO() {
		alunoTemplate = new ThriftColumnFamilyTemplate<String, String>(
				keyspace, CF_ALUNO, stringSerializer, stringSerializer);
	}

	private ColumnFamilyResult<String, String> queryResult;

	@Override
	public void insert(Aluno aluno) throws HectorException {
		final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		Mutator<String> mutatorAluno = HFactory.createMutator(keyspace,
				stringSerializer);

		mutatorAluno.addInsertion(aluno.getMatricula(), CF_ALUNO,
				HFactory.createStringColumn("nome", aluno.getNomeCompleto()));
		mutatorAluno.addInsertion(
				aluno.getMatricula(),
				CF_ALUNO,
				HFactory.createStringColumn("dataNascimento",
						dateFormat.format(aluno.getDataNascimento())));
		mutatorAluno.addInsertion(aluno.getMatricula(), CF_ALUNO, HFactory
				.createStringColumn("curso", aluno.getCursoMatriculado()
						.getCodigo()));

		mutatorAluno.execute();
	}

	@Override
	public List<Aluno> getAll() throws HectorException {
		CqlQuery<String, String, String> cqlQuery = new CqlQuery<String, String, String>(
				keyspace, stringSerializer, stringSerializer, stringSerializer);
		cqlQuery.setQuery("select * from Aluno");
		QueryResult<CqlRows<String, String, String>> result = cqlQuery
				.execute();
		List<Aluno> alunos = new ArrayList<Aluno>();
		if (result.get() == null) {
			return alunos;
		}
		List<Row<String, String, String>> allRows = result.get().getList();

		for (Row<String, String, String> actualRow : allRows) {
			Aluno aluno = new Aluno();
			aluno.setMatricula(actualRow.getKey());
			aluno.setNomeCompleto(actualRow.getColumnSlice().getColumnByName((COLUNA_NOME)).getValue());
			aluno.setDataNascimento(new Date(actualRow.getColumnSlice().getColumnByName((COLUNA_DT_NASCIMENTO)).getValue()));
			aluno.setCursoMatriculado(CursoDAO.getInstance().getByKey(
					actualRow.getColumnSlice().getColumnByName((COLUNA_CURSO)).getValue()));
			alunos.add(aluno);
		}
		return alunos;
	}

	@Override
	public Aluno getByKey(String matricula) throws HectorException {
		Aluno alunoResult = new Aluno();
		queryResult = alunoTemplate.queryColumns(matricula);

		alunoResult.setMatricula(queryResult.getKey());
		alunoResult.setNomeCompleto(queryResult.getString(COLUNA_NOME));
		alunoResult
				.setDataNascimento(queryResult.getDate(COLUNA_DT_NASCIMENTO));

		if (queryResult.getString(COLUNA_CURSO) != null
				&& !queryResult.getString(COLUNA_CURSO).isEmpty()) {
			alunoResult.setCursoMatriculado(CursoDAO.getInstance().getByKey(
					queryResult.getString(COLUNA_CURSO)));
		}
		return alunoResult;
	}

	@Override
	public void delete(Aluno entity) throws HectorException {
		Mutator<String> mutator = HFactory.createMutator(keyspace,
				stringSerializer);
		mutator.addDeletion(entity.getMatricula(), CF_ALUNO, null,
				stringSerializer);
		mutator.execute();
	}

}
